<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>20-计算相机方向向量</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      html,
      body {
        width: 100%;
        height: 100%;
        overflow: hidden;
      }
    </style>
  </head>

  <body>
    <script type="module">
      // 引入three.js
      import * as THREE from "three";
      //引入物理引擎cannon
      import * as Cannon from "cannon";
      import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
      import {
        scene,
        camera,
        renderer,
        createLight,
      } from "../utils/three-base";

      const endPoint = new THREE.Vector3(0, 0, 0);
      camera.position.set(0, 0, 10);
      camera.lookAt(endPoint);

      const direction = new THREE.Vector3();
      camera.getWorldDirection(direction);

      /*
        手动计算：
          坐标中心位置的点坐标 - 相机位置点坐标
          （0,0,0）- （0,0,10）
          （0-0,0-0,0-10）=（0,0,-10）
          求每个分量的二次幂
          求和
          开根号
      */
      function vectorLenth(x, y, z) {
        // x y z 的二次幂
        const x_pow = Math.pow(x, 2);
        const y_pow = Math.pow(y, 2);
        const z_pow = Math.pow(z, 2);
        //求和
        const sum = x_pow + y_pow + z_pow; //100
        //开根号
        const sqrt = Math.sqrt(sum); //10
        const result = new THREE.Vector3(x / sqrt, y / sqrt, z / sqrt);
      }
      vectorLenth(0, 0, -10);

      //用threejs来计算向量相减的结果
      const minus = endPoint.sub(camera.position);
      vectorLenth(minus.x, minus.y, minus.z);

      // 小球相机
      const cubeCamera = new THREE.Mesh(
        new THREE.SphereGeometry(0, 2),
        new THREE.MeshBasicMaterial({
          color: 0xff1ff1,
          wireframe: true,
        })
      );
      //相机位置的向量，缩放0.6得到新的向量
      const pVector = camera.position.clone().multiplyScalar(0.6);
      cubeCamera.position.copy(pVector);
      scene.add(cubeCamera);

      const geometry = new THREE.BufferGeometry().setFromPoints([
        pVector,
        endPoint,
      ]);

      const material = new THREE.LineBasicMaterial({
        color: 0xffffff,
      });
      //相机小球与坐标中心之间的连线
      const line = new THREE.Line(geometry, material);
      scene.add(line);

      //控制插件
      const controls = new OrbitControls(camera, renderer.domElement);
      controls.enableDamping = true; //开启惯性,需要和update方法配合使用

      //动画函数
      function animate() {
        requestAnimationFrame(animate);
        controls.update();
        renderer.render(scene, camera);
      }
      animate();
    </script>
  </body>
</html>
